﻿using HslCommunication;
using HslCommunication.Profinet.Omron;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using YF.NLOG;

namespace ThermoGroupSample.PLC
{
    public class PlcOperation
    {
        private static PlcOperation _instance;
        //private static OmronFinsUdp omronPlc = new OmronFinsUdp("192.168.100.1", 9600);
        private static OmronCipNet omronPlc = new OmronCipNet("192.168.250.1", 44818);
        private bool running = false;
        private string[] strSns;
        private bool isAnalysis = true;
        private int isUpLoad = 0;
        public static PlcOperation Instance
        {
            get
            {
                if (_instance is null)
                {
                    _instance = new PlcOperation();
                }
                return _instance;
            }
        }

        /// <summary>
        /// PLC连接
        /// </summary>
        public bool ConnectPlc()
        {
            //omronPlc.SA1 = 192;
            //omronPlc.GCT = 2;
            //omronPlc.SID = 0;
            //omronPlc.ByteTransform.DataFormat = (HslCommunication.Core.DataFormat)2;
            //omronPlc.ByteTransform.IsStringReverseByteWord = true;
            //IPStatus res = omronPlc.IpAddressPing();
            OperateResult connectResult = omronPlc.ConnectServer();
            if (connectResult.IsSuccess)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Start()
        {
            if (!running)
            { // 确保只有一个线程在运行
                UIUpdate.UpdateControl(FormMain.Instance.richTextBox1, "线程已开启", Color.Blue);
                running = true;
                Thread thread1 = new Thread(new ThreadStart(ReadStart)); // 创建设备动作读取新线程
                Task.Delay(100);
                thread1.Start();
            }
        }

        /// <summary>
        /// 停止读取PLC变量的方法
        /// </summary>
        public void Stop()
        {
            running = false;
        }

        /// <summary>
        /// 读取PLC发送条码组信息、热像仪到位测试信号、温差测试结果
        /// 1、读取测试开始信号
        /// 2、开始测试信号为true时，同时获取条码信息以及温差测试结果信息缓存
        /// 3、每次读取完成后发送读取完成信号给PLC
        /// 4、热像仪测试完成后，OK则生成流水号，并将结果全部上传MES
        /// 5、同时将测试结果发送给PLC，NG需剔除
        /// </summary>
        private async void ReadStart()
        {
            while (true)
            {
                try
                {
                    OperateResult<short> allowStart = await omronPlc.ReadInt16Async(XmlConfigManager.ConfigInstance["PLC:WorkStart:ReadAddress:TempTest"]);//热成像开始测试信号
                    if (allowStart.IsSuccess)
                    {
                        //1、热成像测试开始，不等于0触发
                        int isRead = allowStart.Content;
                        bool writePlcRes = true;
                        if (isRead != 0 && isAnalysis)
                        {
                            isAnalysis = false;

                            //3.1、 发送给PLC测试中
                            WriteToPlc("热成像测试中", XmlConfigManager.ConfigInstance["PLC:WorkStart:WriteAddress:TestIng1"], 1);
                            //3.2、 调用热成像方法，并发送给PLC测试结果
                            var testResults = await FormMain.Instance.mCameras[0].infrared.GetRectPoinTemp();
                            for (int i = 0; i < testResults.Length; i++)
                            {
                                short setVals = (testResults[i] == true ? (short)785 : (short)273);
                                var operateResult = omronPlc.Write(XmlConfigManager.ConfigInstance["PLC:WorkStart:WriteAddress:TestIng" + (i + 1).ToString()], setVals);
                                if (!operateResult.IsSuccess)
                                {
                                    LoggerHelper._log.Trace($"【热成像测试完成】，PLC写入失败：{operateResult.Message}");
                                    UIUpdate.UpdateControl(FormMain.Instance.richTextBox1, "热成像测试完成，PLC写入失败", Color.Red);
                                    writePlcRes = false;
                                    break;
                                }
                            }
                            if (writePlcRes)
                            {
                                LoggerHelper._log.Trace("【热成像测试完成】，PLC写成功");
                                UIUpdate.UpdateControl(FormMain.Instance.richTextBox1, "热成像测试完成，PLC写入成功", Color.Blue);
                            }

                            //3.3、 处理MES业务信息

                            isAnalysis = true;
                        }
                    }
                    else
                    {
                        LoggerHelper._log.Trace("【读取PLC热成像开始测试信号失败】：" + allowStart.Message);
                    }

                    OperateResult<short> allowResult = await omronPlc.ReadInt16Async(XmlConfigManager.ConfigInstance["PLC:WorkStart:ReadAddress:AllResult"]);//获取所有结果信息
                    if (allowResult.IsSuccess)
                    {
                        int isRead = allowResult.Content;
                        if (isRead != 0 && isRead != isUpLoad)
                        {
                            isUpLoad = isRead;
                            for (int i = 0; i < 8; i++)
                            {

                            }
                        }
                    }
                    else
                    {
                        LoggerHelper._log.Trace("【读取PLC热成像测试结果信息失败】：" + allowResult.Message);
                    }
                }
                catch (Exception ex)
                {
                    //LoggerHelper._log.Trace("", ex);
                }

                Thread.Sleep(100);
            }
        }

        /// <summary>
        /// PLC写（BOOL）
        /// </summary>
        /// <param name="msg">功能描述</param>
        /// <param name="address">写入地址</param>
        /// <param name="result">写入结果</param>
        /// <returns></returns>
        public void WriteToPlc(string msg, string address, bool result)
        {
            var operateResult = omronPlc.Write(address, result);
            if (operateResult.IsSuccess)
            {
                LoggerHelper._log.Trace($"{msg}，写入PLC成功");
            }
            else
            {
                LoggerHelper._log.Trace($"{msg}，写入PLC失败，失败原因：{operateResult.Message}");
            }
        }

        /// <summary>
        /// PLC写（String）
        /// </summary>
        /// <param name="msg">功能描述</param>
        /// <param name="address">写入地址</param>
        /// <param name="result">写入结果</param>
        /// <returns></returns>
        public void WriteToPlc(string msg, string address, short result)
        {
            var operateResult = omronPlc.Write(address, result);
            if (operateResult.IsSuccess)
            {
                LoggerHelper._log.Trace($"【{msg}】，写入PLC成功");
            }
            else
            {
                LoggerHelper._log.Trace($"【{msg}】，写入PLC失败，失败原因：{operateResult.Message}");
            }
        }
    }
}
